Bump aiosendspin to 9.1.1 and wire up pairing/encryption - #277
Conversation
sendspin-python-cli was pinned to aiosendspin~=6.0.1, three major versions and 77 commits behind, and never adopted the encryption/pairing subsystem that landed in that gap. This bumps the dependency to 9.1.1 and: - Persists a per-client Identity (X25519 keypair) and FileClientPairingStore under --settings-dir (now available for the TUI too, not just daemon). - Wires PairingSupport into both SendspinClient constructions (TUI, daemon), rendering a dynamic pairing PIN in a new "Pairing Required" TUI panel or logging it in daemon mode. - Fixes everything else the version bump broke: the client-state enum removal, server/hello restructuring, ServerInfo/GoodbyeReason changes, and the server-side identity/pairing_store constructor change (affects `sendspin serve` too). - Fixes a real bug surfaced by live testing against a Music Assistant server: SendspinClient.attach_websocket() now blocks for the connection's entire lifetime once admitted (previously it returned right after handshake), so the daemon's server-initiated listener never reached its own post-handshake audio/MPRIS wiring. Audio chunks flowed at the protocol level but never reached local playback. Fixed by running attach_websocket() as a background task and polling client.connected, matching the pattern aiosendspin's own tests use for this scenario. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Spell out that the daemon-mode PIN is log-only (journalctl under systemd) with no unattended-pairing surface, since that's easy to miss compared to the TUI's dedicated panel. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
I think the upgrade path for a previously installed and paired server is broken: I ran the following: uv tool uninstall sendspin
uv tool install "git+https://github.com/OnFreund/sendspin-python-cli.git@modernize-aiosendspin-pairing"I get the following logs: But nothing plays out of the speakers. |
Addresses feedback on PR Sendspin#277: upgrading from a pre-pairing install replaces the old free-text client_id with one derived from a generated identity's public key, so the client now looks like a new device to any server that keyed player state off the old client_id. That change itself can't be avoided (client_id is cryptographically bound to the identity's keypair, not an arbitrary label), but: - Log a one-time warning when a fresh identity is generated for a settings dir that already had an old-style client_id, explaining what happened and that the player may need to be re-added on the server. - Populate DeviceInfo.mac_address (a stable hardware identifier the protocol already supports but this client never sent) so servers that support device-based reconciliation have something durable to key off, independent of client_id. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Thanks for testing this against a real Music Assistant setup — really helpful. I think what you're hitting is a real (and somewhat unavoidable) consequence of adding I just pushed two things that address what's actually in our control here:
That said, I want to make sure we're not also looking at a second, separate bug: your log
If audio genuinely doesn't work even on the new player once selected, that's a distinct bug 🤖 Generated with Claude Code |
|
Tested Setup: Raspberry Pi 4B, HiFiBerry Amp100 (pcm512x), Debian 13 (trixie), kernel Baseline: released
|
mrwsl's PR Sendspin#277 test found a ~64s silent stall on the first incoming connection before the server retries and admission succeeds. Root cause: aiosendspin's own Noise handshake timeout (30s) is caught internally by attach_websocket() and returns normally rather than raising, so our polling loop's exc-is-not-None check never fires and we return with no log line at all. Add an info-level log for that branch so a stalled first attempt is visible instead of looking identical to nothing happening. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
@mrwsl thank you for this — genuinely one of the most thorough test reports I've seen, exactly the confirmation this needed. Great to hear audio holds up cleanly over a real 5-minute session with skips/pause/volume changes and no stalls. Your first-connection trace was really useful: the ~64s silent gap before MA's retry is caused by aiosendspin's own Noise handshake timeout (30s) being caught internally by @chriscn — this may well be what you hit too: your log cuts off at exactly the same 🤖 Generated with Claude Code |
sendspin-python-cli was pinned to aiosendspin~=6.0.1, three major versions and 77 commits behind, and never adopted the encryption/pairing subsystem that landed in that gap. This bumps the dependency to 9.1.1 and:
sendspin servetoo).